<!--
 * @Author: 梁青春
 * @Date: 2025-03-10 13:19:20
 * @LastEditTime: 2025-03-11 14:21:39
 * @LastEditors: 梁青春
-->
<template>
  <div class="unreal-viewer" ref="viewerContainer"></div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, reactive, watch } from 'vue'
import { Config, PixelStreaming } from '@epicgames-ps/lib-pixelstreamingfrontend-ue5.5'
import { coordinateMapper } from '@/utils/CoordinateMapper.js'

const viewerContainer = ref(null)
const streamState = reactive({
  isFullscreen: false,
  isMuted: false,
  isConnected: false,
  connectionStatus: 'disconnected',
  retryCount: 0
})

const MAX_RETRIES = 5
const BASE_DELAY = 3000

// 事件处理函数
const handleConnect = () => {
  streamState.connectionStatus = 'connected'
  streamState.retryCount = 0
}

// 事件处理函数
const handleDisconnect = () => {
  streamState.connectionStatus = 'disconnected'
  attemptReconnect()
}

const handleError = error => {
  console.error('Streaming error:', error)
  streamState.connectionStatus = 'error'
}

const attemptReconnect = () => {
  if (streamState.retryCount < MAX_RETRIES) {
    const delay = BASE_DELAY * Math.pow(2, streamState.retryCount)
    setTimeout(() => {
      streamState.retryCount++
      stream.connect()
    }, delay)
  }
}

// 在卸载时移除事件监听
onUnmounted(() => {
  if (stream) {
    stream.removeEventListener('connected', handleConnect)
    stream.removeEventListener('disconnected', handleDisconnect)
    stream.removeEventListener('error', handleError)
    clearTimeout(reconnectTimer)
  }
})
let stream = null
let reconnectTimer = null

onMounted(() => {
  console.log(viewerContainer.value)

  if (viewerContainer.value) {
    const config = new Config({
      initialSettings: {
        ss: `ws://192.168.1.54:8080/`,
        ShowToolbar: false,
        VideoEncoder: 'H264',
        ForceH264: true,
        streamerId: ''
      },
      useUrlParams: false
    })

    try {
      stream = new PixelStreaming(config)
      viewerContainer.value.appendChild(stream.videoElementParent)

      // 添加事件监听
      stream.addEventListener('connected', handleConnect)
      stream.addEventListener('disconnected', handleDisconnect)
      stream.addEventListener('error', handleError)

      // 添加响应事件监听
      stream.addResponseEventListener('handle_responses', handleResponseFunction)

      // 建立连接
      stream.connect()
    } catch (error) {
      console.error('初始化 Pixel Streaming 时出错:', error)
    }
  }
  // 监听窗口大小变化
  const resizeObserver = new ResizeObserver(() => {
    coordinateMapper.initSceneParams({ ueMinX: 0, ueMaxX: 1920, ueMinY: 0, ueMaxY: 1080 }, viewerContainer.value)
  })

  resizeObserver.observe(viewerContainer.value)
})

onUnmounted(() => {
  if (stream) {
    stream.removeResponseEventListener('handle_responses')
    stream.disconnect()
    stream = null
  }
  resizeObserver.disconnect()
})

const emit = defineEmits(['coordinates-updated', 'connection-change', 'connection-msg'])

// 处理响应的函数
const handleResponseFunction = data => {
  console.warn('Response received!', data)
  emit('coordinates-updated', data)
}

const CallUE = msg => {
  if (stream) {
    stream.emitUIInteraction(msg)
    return true
  }
  return false
}

// 在坐标转换方法中添加事件发射
const handleCoordinateUpdate = (screenX, screenY, ueX, ueY) => {
  emit('coordinates-updated', {
    screen: { x: screenX, y: screenY },
    ue: { x: ueX, y: ueY }
  })
}

// 在连接状态变化时触发事件
watch(
  () => streamState.connectionStatus,
  newVal => {
    emit('connection-change', newVal)
  }
)
defineExpose({
  CallUE,
  handleCoordinateUpdate
})
</script>

<style scoped>
.unreal-viewer {
  width: 100%;
  height: 100%;
  background-color: #000;
}
</style>
